徒弟今天一覺醒來,忍不住掩嘴笑著說「呵呵,真是學習的太認真了,還夢見 map() 是個人呢,呵呵。繼續練習吧~」
徒弟:師傅,我試著計算在 TODO陣列 裡面.completed=true
的數量,但似乎不太對。我用了這個指令:.[] | select(.completed == true) | length
師傅:嗯,接近了。但你忽略了一個重要步驟。
徒弟:是嗎?我哪裡做錯了?
師傅:你的 select()
沒錯,但 length
的位置不對。試試這個:[.[] | select(.completed == true)] | length
徒弟:哦!我明白了,我們需要先將選中的元素放入一個新的陣列中,然後再計算長度。
師傅:沒錯。方括號 []
創建了一個新陣列。
徒弟:那麼,對於 .completed=false
的數量,我可以用類似的方法?
師傅:正確。試試看。
徒弟:好的,讓我試試:[.[] | select(.completed == false)] | length
師傅:完美。你已經掌握了精髓。
徒弟:謝謝師傅!我現在理解得更清楚了。這樣我們就可以靈活地計算各種條件的元素數量了。
師傅:沒錯。記住,在 jq 中,先構建你想要的資料結構,然後再進行操作,通常會得到更好的結果。
徒弟:明白了,師傅。對了,師傅,教師節快樂!😊
師傅:這麼突然,呵呵。😊
徒弟:師傅,我又有疑問了。這個情境也能使用 map()
嗎?
師傅:說得好。讓我們來討論一下用 map()
的情況。
徒弟:好的,師傅。用 map()
會怎麼寫呢?
師傅:使用 map()
的話,可以這樣寫:map(select(.completed == false)) | length
徒弟:哦,看起來更簡潔了。這樣寫有什麼優點嗎?
師傅:優點是寫法更簡潔,可讀性更高。如果你更注重可讀性,使用 map()
是個好選擇。如果你在處理非常大的資料集,並且性能是首要考慮因素,那麼 [.[] | select(...)]
可能更合適。
徒弟:謝謝師傅,這讓我對兩種方法的使用情境有了更清晰的認識。
師傅:很好。
先前我們在 Day7: 使用 jq filter 處理 JSON 陣列 學過「length 取得長度」,對於陣列而言 | length
可以取得陣列中元素的數量,jq 'length' todos.json
參考下圖:
但是對於物件而言,| length
是鍵值對(key-value pairs)的數量,jq '.[] | length' todos.json
參考下圖:
有注意到,.[]
是把每個元素個別取出,所以變成計算每一個元素鍵值對(key-value pairs)的數量了。因此,要計算出篩選過後的陣列長度、元素數量,我們需要把資料組成新的陣列。
[]
jq -c '[.[] | select(.completed==true)] | length'
map()
jq -c 'map( select(.completed==true) ) | length'
在 Day8: jq filter 組合使用 pipe 我們透過 「select 過濾函式」來篩選資料;我習慣篩選資料之後,都去看一下篩選出來的結果有多少筆,這時候 | length
就是很適合的工具。使用 jq filter 看陣列的長度,要確認輸入給 | length
的資料是陣列,才會得到正確的結果。
今天教師節,敬祝老師們:教師節快樂~😊